package com.zjf.fupload.popup.actions;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.jobs.JobChangeAdapter;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.internal.core.JarPackageFragmentRoot;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.handlers.HandlerUtil;

import com.zjf.fupload.FUploadPlugin;
import com.zjf.fupload.entity.ServerInfo;
import com.zjf.fupload.ftp.FTPUploader;
import com.zjf.fupload.ftp.UploadException;
import com.zjf.fupload.ftp.UploadListenerAdapter;
import com.zjf.fupload.util.FileUtil;

/**
 * 菜单点击操作
 * @author zjf
 */
@SuppressWarnings("restriction")
public class DoUploadAction extends AbstractHandler {
	
	@SuppressWarnings("unused")
	private String path;

	@Override
	public Object execute(ExecutionEvent event) throws ExecutionException {

		IWorkbenchWindow window = HandlerUtil
				.getActiveWorkbenchWindowChecked(event);
		ISelection selection = window.getSelectionService().getSelection();
		
		List<File> files = new ArrayList<File>();
		
		if(!(selection instanceof IStructuredSelection)) {
			MessageDialog.openInformation(window.getShell(), FUploadPlugin.NAME,
					"暂不支持该操作");
			return null;
		} else {
				IStructuredSelection structureSelection = (IStructuredSelection) selection;
				
				
				File tempFile = null;
				
				Iterator<?> iter = structureSelection.iterator();
				while(iter.hasNext()) {
					
					Object obj = iter.next();
					
					IResource resource = null;
					String path = null;
					// common resource file
					if (obj instanceof IFile) {
						resource = (IResource) obj;
						path = resource.getLocation().toOSString();
						tempFile = resource.getLocation().toFile();
						path = path.substring(0, path.lastIndexOf(File.separator));
					}
					// other resource such as folder,project
					else if (obj instanceof IResource) {
						resource = (IResource) obj;
						tempFile = resource.getLocation().toFile();
						path = resource.getLocation().toOSString();
					}
					// explorer java element, contain field,method,package
					else if (obj instanceof IJavaElement) {
						// jar resource is null
						if (obj instanceof JarPackageFragmentRoot) {
							path = ((IPackageFragmentRoot) obj).getPath().toOSString();
							tempFile = ((IPackageFragmentRoot) obj).getPath().toFile();
							// get folder
							path = path.substring(0, path.lastIndexOf(File.separator));
						} else if (obj instanceof IPackageFragmentRoot) {
							// src folder
							String prjPath = ((IPackageFragmentRoot) obj)
									.getJavaProject().getProject().getParent()
									.getLocation().toOSString();
							path = prjPath
									+ ((IPackageFragmentRoot) obj).getPath()
											.toOSString();
							
							tempFile = new File(prjPath + ((IPackageFragmentRoot) obj).getPath().toOSString());
						} else if (obj instanceof IPackageFragment) {// other : package
							resource = ((IPackageFragment) obj).getResource();
							path = resource.getLocation().toOSString();
							tempFile = resource.getLocation().toFile();
						} else if(obj instanceof IJavaProject) {
							resource = ((IJavaProject) obj).getProject();
							tempFile = resource.getLocation().toFile();
							path = resource.getLocation().toOSString();
						} else {// member:filed:
							resource = ((IJavaElement) obj).getResource();
							tempFile = resource.getLocation().toFile();
							path = resource.getLocation().toOSString();
							// get folder
							path = path.substring(0, path.lastIndexOf(File.separator));
						}

					}
//					// explorer team ui resource
//					else if (obj instanceof ISynchronizeModelElement) {
//						resource = ((ISynchronizeModelElement) obj).getResource();
//						tempFile = resource.getLocation().toFile();
//						path = resource.getLocation().toOSString();
//					}
					
					if(tempFile != null) {
						files.add(tempFile);
						this.path = path;
					}
			}
		}
		
		if(!files.isEmpty()) {
			
			ChoosePathDialog chooseDialog = new ChoosePathDialog(window.getShell());
			int clickType = chooseDialog.open();
			
			if(clickType == Dialog.OK) {
				
				try {
					ServerInfo info = chooseDialog.getConfirmServerInfo();
					Job job = new UploadJob(info, files.toArray(new File[0]));
					job.schedule();
				} catch(Throwable expt) {
					ByteArrayOutputStream out = new ByteArrayOutputStream();
					PrintStream print = new PrintStream(out);
					expt.printStackTrace(print);
					MessageDialog.openError(window.getShell(), FUploadPlugin.NAME,
							out.toString());
				}
			}
		} else {
			MessageDialog.openWarning(window.getShell(), FUploadPlugin.NAME, "暂不支持该操作");
		}

		return null;
	}
	
	static class UploadJob extends Job {  
		
		ServerInfo info;
		File[] files;
		FTPUploader uploader;
		
        public UploadJob(ServerInfo info, File[] files) {
        	super(FUploadPlugin.NAME);  
        	this.info = info;
        	this.files = files;
            
        	uploader = new FTPUploader(info.getServer(), info.getPath());
			uploader.setUsername(info.getUsername());
			uploader.setPassword(info.getPassword());
			uploader.setPort(info.getPort());
        	
            this.addJobChangeListener(new JobChangeAdapter() {
				@Override
				public void done(IJobChangeEvent event) {
					IStatus status = event.getResult();
					if(status.getCode() == IStatus.CANCEL) {
						uploader.setCanceled(true);
					} else if(status.getCode() == IStatus.ERROR) {
						uploader.setCanceled(true);
					} 
				}
            	
            });
        }  
  
        public IStatus run(IProgressMonitor monitor) {  
        	
        	final IProgressMonitor lMonitor = monitor;
        	
        	uploader.setListener(new UploadListenerAdapter() {
				@Override
				public void transferred(long total, long len) {
					lMonitor.worked((int)len);
				}

				@Override
				public void fileUploadStart(File file) {
					lMonitor.setTaskName("upload file: " + file.getAbsolutePath());
				}
				
        	});
        	
			lMonitor.beginTask("upload files", (int)FileUtil.getSize(files));  
            
			try {
				uploader.upload(files);
			} catch (UploadException e) {
				throw new RuntimeException(e.getCause());
			}
           
			lMonitor.done();
            
            return Status.OK_STATUS;  
        }  
    }  

}
